<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script>
    // 1.我们js引擎运行s 分为两步：预解析  代码执行
    // (1) 预解析 js 引擎会把js 里面所有的 var 还有function 提示到当前作用域的最前面
    // (2) 代码执行  按照代码书写的顺序从上往下执行
    // 2.预解析分为 变量预解析（变量提升）和 函数预解析（函数提升）
    // (1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面，不提示赋值操作
    // (2) 函数提升 就是把所有的函数声明提升到当前作用域的最前面，不调用函数

    console.log(num); // undefined
    var num = 10;

    //相当于执行了以下代码
    var num;
    console.log(num);
    num = 10;

    // 预解析案例1：
    var num1 = 10;
    fun();
    function fun () {
      console.log(num1);
      var num1 = 20;
    }

    // 相当于执行以下代码
    var num1;
    function fun () {
      var num1;
      console.log(num1); // undefined
      num1 = 20;
    }
    num1 = 10;
    fun();

    // 预解析案例2：
    var num2 = 10;
    function fn () {
      console.log(num2);
      var num2 = 20;
      console.log(num2);
    }
    fn();

    // 相当于执行以下代码
    var num2;
    function fn () {
      var num2;
      console.log(num2);  // undefined
      num2 = 20;
      console.log(num2); // 20
    }
    num2 = 10;
    fn();

    // 预解析案例3：
    f1();
    console.log(c);
    console.log(b);
    console.log(a);
    function f1 () {
      var a = b = c = 9;
      // 相当于 var a = 9; b = 9; c = 9;   b 和 c 直接赋值，没有var声明，当全局变量看
      // 集体声明 var a = 9; b = 9; c = 9;
      console.log(a);
      console.log(b);
      console.log(c);
    }

    // 相当于执行以下代码
    function f1 () {
      var a;
      a = b = c = 9;
      console.log(a); // 9
      console.log(b); // 9
      console.log(c); // 9
    }
    f1();
    console.log(c); // 9
    console.log(b); // 9
    console.log(a); // 报错

  </script>
</head>

<body>

</body>

</html>